package com.tcm.utils;

import com.tcm.TcmApplication;
import lombok.extern.slf4j.Slf4j;
import org.csource.fastdfs.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Properties;

/**
 * @program: yeb
 * @description: FastDFS工具类
 * @author: Jason
 * @create: 2023-05-14 21:35
 */
@Slf4j
public class FastDFSUtils {
    /**
     * @des:类加载时初始化客户端
     **/
//    static {
//        try {
//            String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
//            /*读取配置文件，并初始化对应的属性*/
//            ClientGlobal.init(filePath);
//        } catch (Exception e) {
//            log.error("初始化FastDFS失败",e);
//        }
//    }

    static {
        try {
            Properties properties = new Properties();
            // 使用ClassLoader加载properties配置文件生成对应的输入流
            InputStream in = TcmApplication.class.getClassLoader().getResourceAsStream("fdfs_client.properties");
            properties.load(in);
            ClientGlobal.initByProperties(properties);
        } catch (Exception e) {
            log.error("初始化FastDFS失败",e);
        }

    }

    /*
    static {
        String filePath = "/usr/app/fdfs_client.conf";
        try (InputStream inputStream = FastDFSUtils.class.getClassLoader().getResourceAsStream("fdfs_client.conf");
             FileOutputStream outputStream = new FileOutputStream(filePath)
        ) {
            IOUtils.copy(inputStream, outputStream);
            ClientGlobal.init(filePath);
        } catch (Exception e) {
            log.error("初始化FastDFS失败", e);
        }
    }
     */


    /**
     * @des: 上传文件
     * @param: file 上传文件
     * @return: String[]  String[0]为组名  String[1]为文件名
     **/
    public static String[] upload(MultipartFile file) throws Exception {
        String[] results = null;
        StorageClient storageClient = null;
        try {
            String filename = file.getOriginalFilename();
            storageClient = getStorageClient();
            /*文件后缀名*/
            String fileExt = filename.substring(filename.lastIndexOf(".") + 1);
            /*上传文件
             * 参数一：文件字节流
             * 参数二：文件后缀名
             * 参数三：元数据信息，一般保存在mysql数据库*/
            results = storageClient.upload_file(file.getBytes(), fileExt, null);
        } catch (Exception e) {
            log.info("上传文件失败=====>{}", storageClient.getErrorCode());
            throw new Exception("上传文件失败");
        }
        if (null == results) {
            log.error("上传文件失败=====>{}", storageClient.getErrorCode());
            throw new Exception("上传文件失败");
        }
        return results;
    }

    /**
     * @des: 获取用户访问服务器中头像的路径前缀。
     * 用法：当浏览器需要访问图片时，图片url路径为：  getTrackerUrl()+图片组名+"/"+图片远程文件名
     * @return: String
     **/
    public static String getTrackerUrl() {
        TrackerClient trackerClient = null;
        TrackerServer trackerServer = null;
        StorageServer storeStorage = null;
        try {
            trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
            storeStorage = trackerClient.getStoreStorage(trackerServer);
        } catch (Exception e) {
            log.error("文件路径获取失败====>{}", e.getMessage());
        }
        /*即返回fdfs服务器地址+nginx反向代理的端口号，用以浏览器通过url地址直接查看图片*/
        return "http://" + storeStorage.getInetSocketAddress().getHostString() + ":85/";
    }


    /**
     * @des: 获取文件信息
     * @param: groupName 组名
     * @param: remoteFileName 远程文件名
     * @return: FileInfo
     **/
    public static FileInfo getFileInfo(String groupName, String remoteFileName) throws Exception {
        StorageClient storageClient = null;
        try {
            storageClient = getStorageClient();
            FileInfo fileInfo = storageClient.get_file_info(groupName, remoteFileName);
            return fileInfo;
        } catch (Exception e) {
            log.error("文件信息获取失败=====>{}", storageClient.getErrorCode());
            throw new Exception("文件信息获取失败");
        }
    }

    /**
     * @des: 下载文件
     * @param: groupName  组名
     * @param: remoteFilename  远程文件名
     * @return: InputStream
     **/
    public static InputStream downloadFile(String groupName, String remoteFilename) throws Exception {
        StorageClient storageClient = null;
        try {
            storageClient = getStorageClient();
            /*下载文件*/
            byte[] fileBytes = storageClient.download_file(groupName, remoteFilename);
            InputStream inputStream = new ByteArrayInputStream(fileBytes);
            return inputStream;
        } catch (Exception e) {
            log.error("文件下载失败=====>{}", storageClient.getErrorCode());
            throw new Exception("文件下载失败");
        }
    }

    /**
     * @des: 删除文件
     * @param: groupName  组名
     * @param: remoteFileName  文件名
     * @return: int
     **/
    public static int deleteFile(String groupName, String remoteFileName) throws Exception {
        StorageClient storageClient = null;
        try {
            storageClient = getStorageClient();
            /*下载文件*/
            int i = storageClient.delete_file(groupName, remoteFileName);
            return i;
        } catch (Exception e) {
            log.info("文件删除失败=====>{}", storageClient.getErrorCode());
            throw new Exception("文件下载失败");
        }
    }


    /**
     * @des: 生成TrackerServer，不用管
     * @return: TrackerServer
     **/
    private static TrackerServer getTrackerServer() {
        TrackerServer trackerServer = null;
        try {
            TrackerClient trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
        } catch (Exception e) {
            log.error("初始化TrackerServer失败", e);
        }
        return trackerServer;
    }

    /**
     * @des: 生成storage客户端，不用管
     * @return: StorageClient
     **/
    private static StorageClient getStorageClient() {
        TrackerServer trackerServer = getTrackerServer();
        StorageClient storageClient = new StorageClient(trackerServer, null);
        return storageClient;
    }

}
